#include "main.h"
#include "ParsePAT.h"
#include "ParsePMT.h"
#include "ParseNIT.h"
#include "ParseBAT.h"
#include "ParseSDT.h"
#include "ParseEIT.h"
#include "ParseDescriptor.h"

void Get_PMT();
void Get_NIT();
void Get_BAT();
void Get_SDT();
void Get_EIT();

enum TABLE
{
    PMT = 1, NIT, BAT, SDT, EIT, EXIT
};

void GetInfo()
{
    enum TABLE ts_table;

    while (1)
    {
        printf("Please enter the table you want to find ：1.PMT 2.NIT 3.BAT 4.SDT 5. EIT 6.EXIT\n");

        scanf("%d",(int *)&ts_table);
        
        switch (ts_table)
        {
            case PMT:
                Get_PMT();
            break;
        
            case NIT:
                Get_NIT();
            break;

            case BAT:
                Get_BAT();
            break;

            case SDT:
                Get_SDT();
            break;

            case EIT:
                Get_EIT();
            break;

            case EXIT:
                return;

            default:
            break;
        }
    }
}

void Get_PMT()
{

    TS_PMT *Pmt_Info_Point = TS_PackagePmtPoint->next;
    
    if(Pmt_Info_Point != NULL)
    do{
        printf("--------------------------PMT-----------------------------\n");
        printf("table_id = %x\n",Pmt_Info_Point->table_id);
        printf("section_syntax_indicator = %x\n",Pmt_Info_Point->section_syntax_indicator);
        printf("zero = %x\n",Pmt_Info_Point->zero);
        printf("reserved_1 = %x\n",Pmt_Info_Point->reserved_1);
        printf("section_length = %d\n",Pmt_Info_Point->section_length);
        printf("program_number = %x\n",Pmt_Info_Point->program_number);
        printf("reserved_2 = %x\n",Pmt_Info_Point->reserved_2);
        printf("version_number = %x\n",Pmt_Info_Point->version_number);
        printf("current_next_indicator = %x\n",Pmt_Info_Point->current_next_indicator);
        printf("section_number = %x\n",Pmt_Info_Point->section_number);
        printf("last_section_number = %x\n",Pmt_Info_Point->last_section_number);
        printf("reserved_3 = %x\n",Pmt_Info_Point->reserved_3);
        printf("PCR_PID = %x\n",Pmt_Info_Point->PCR_PID);
        printf("reserved_4 = %x\n",Pmt_Info_Point->reserved_4);
        printf("program_info_length = %d\n",Pmt_Info_Point->program_info_length);
        printf("CRC_32 = %x\n",Pmt_Info_Point->CRC_32);

        if (0 != Pmt_Info_Point->program_info_length)
	    {
            ParseTS_Descriptor(Pmt_Info_Point->program_info_descriptor);
	    }

        int PmtStreamPosition = 12;
        int PmtStreamCount = 0;
        int PMT_Length = (Pmt_Info_Point->section_length) + 3;

        for(PmtStreamPosition += Pmt_Info_Point->program_info_length; PmtStreamPosition < (PMT_Length - 4); PmtStreamPosition 
                    += 5)
        {
         
            if(Pmt_Info_Point->astPMT_Stream[PmtStreamCount].ES_info_length != 0)
            {
                ParseTS_Descriptor(Pmt_Info_Point->astPMT_Stream[PmtStreamCount].descriptor);
                PmtStreamPosition += Pmt_Info_Point->astPMT_Stream[PmtStreamCount].ES_info_length;
            }
            
            printf("-------------------------PMTSTEAM--------------------------\n");
            printf("stream_type = %x\n",Pmt_Info_Point->astPMT_Stream[PmtStreamCount].stream_type);
            printf("reserved_5 = %x\n",Pmt_Info_Point->astPMT_Stream[PmtStreamCount].reserved_5);
            printf("elementary_PID = %x\n",Pmt_Info_Point->astPMT_Stream[PmtStreamCount].elementary_PID);
            printf("reserved_6 = %x\n",Pmt_Info_Point->astPMT_Stream[PmtStreamCount].reserved_6);
            printf("ES_info_length = %d\n",Pmt_Info_Point->astPMT_Stream[PmtStreamCount].ES_info_length);
            PmtStreamCount++;
        }

        Pmt_Info_Point = Pmt_Info_Point->next;
    }while (Pmt_Info_Point != NULL);
}

void Get_NIT()
{
    TS_NIT *Nit_Info_Point = TS_PackageNitPoint->next;

    if(Nit_Info_Point != NULL)
    do{
        printf("-----------------------------NIT----------------------------\n");
        printf("table_id = %x\n",Nit_Info_Point->table_id);
        printf("section_syntax_indicator = %x\n",Nit_Info_Point->section_syntax_indicator);
        printf("reserved_future_use_1 = %x\n",Nit_Info_Point->reserved_future_use_1);
        printf("section_length = %d\n",Nit_Info_Point->section_length);
        printf("network_id = %x\n",Nit_Info_Point->network_id);
        printf("reserved_2 = %x\n",Nit_Info_Point->reserved_2);
        printf("version_number = %x\n",Nit_Info_Point->version_number);
        printf("current_next_indicator = %x\n",Nit_Info_Point->current_next_indicator);
        printf("section_number = %x\n",Nit_Info_Point->section_number);
        printf("last_section_number = %x\n",Nit_Info_Point->last_section_number);
        printf("reserved_fututare_use_2 = %x\n",Nit_Info_Point->reserved_future_use_2);
        printf("network_descriptors_length = %d\n",Nit_Info_Point->network_descriptors_length);
        printf("reserved_future_use_2 = %x\n",Nit_Info_Point->reserved_future_use_2);
        printf("transport_stream_loop_length = %d\n",Nit_Info_Point->transport_stream_loop_length);
        printf("CRC_32 = %x\n",Nit_Info_Point->CRC_32);
        
        if(Nit_Info_Point->network_descriptors_length != 0)
        {
            ParseTS_Descriptor(Nit_Info_Point->network_descriptor);
        }
        
        int NetworkDescriptorLen = Nit_Info_Point->network_descriptors_length;
        int TransportPosition = 10 + NetworkDescriptorLen + 2;
        int NIT_Length = Nit_Info_Point->section_length + 3;
        int TranportCount = 0;

        if(Nit_Info_Point->transport_stream_loop_length != 0)
        {
            for (TransportPosition; TransportPosition < NIT_Length - 4; TransportPosition += 6)
            {
                if (0 != Nit_Info_Point->astNIT_Transport[TranportCount].transport_descriptors_length)
                {
                    ParseTS_Descriptor(Nit_Info_Point->astNIT_Transport[TranportCount].descriptor);
                    TransportPosition += Nit_Info_Point->astNIT_Transport[TranportCount].transport_descriptors_length;
                }

                printf("-----------------------------NITSection----------------------------\n");
                printf("transport_stream_id = %x\n",Nit_Info_Point->astNIT_Transport[TranportCount].transport_stream_id);
                printf("original_network_id = %x\n",Nit_Info_Point->astNIT_Transport[TranportCount].original_network_id);
                printf("reserved_future_use = %x\n",Nit_Info_Point->astNIT_Transport[TranportCount].reserved_future_use);
                printf("transport_descriptors_length = %x\n",Nit_Info_Point->astNIT_Transport[TranportCount].transport_descriptors_length);

                TranportCount++;
            }
        }

        Nit_Info_Point = Nit_Info_Point->next;
    }while (Nit_Info_Point != NULL);
}

void Get_BAT()
{
    TS_BAT *Bat_Info_Point = TS_PackageBatPoint->next;

    if(Bat_Info_Point != NULL)
    do{
        printf("------------------------BAT---------------------------\n");
        printf("talble_id = %x\n",Bat_Info_Point->table_id);
        printf("section_syntax_indicator = %x\n",Bat_Info_Point->section_syntax_indicator);
        printf("reserved_future_use_1 = %x\n",Bat_Info_Point->reserved_future_use1);
        printf("reserved_1 = %x\n",Bat_Info_Point->reserved1);
        printf("section_length = %x\n",Bat_Info_Point->section_length);
        printf("bouquet_id = %x\n",Bat_Info_Point->bouquet_id);
        printf("reserved_2 = %x\n",Bat_Info_Point->reserved2);
        printf("version_number = %x\n",Bat_Info_Point->version_number);
        printf("current_next_indicator = %x\n",Bat_Info_Point->current_next_indicator);
        printf("section_number = %x\n",Bat_Info_Point->section_number);
        printf("last_section_numberr = %x\n",Bat_Info_Point->last_section_number);
        printf("reserved_future_use2 = %x\n",Bat_Info_Point->reserved_future_use2);
        printf("bouquet_descriptors_length = %x\n",Bat_Info_Point->bouquet_descriptors_length);
        printf("reserved_future_use3  = %x\n",Bat_Info_Point->reserved_future_use3);
        printf("transport_stream_loop_length  = %x\n",Bat_Info_Point->transport_stream_loop_length);
        printf("CRC_32  = %x\n",Bat_Info_Point->CRC_32);

        if(Bat_Info_Point->bouquet_descriptors_length != 0)
        {
            ParseTS_Descriptor(Bat_Info_Point->descriptor);
        }

        int SectionCount = 0;
        int SectionPosition = Bat_Info_Point->bouquet_descriptors_length+12;
        int BAT_Length = Bat_Info_Point->section_length + 3;

        if(Bat_Info_Point->transport_stream_loop_length != 0)
        {
            for (SectionPosition; SectionPosition < BAT_Length - 4; SectionPosition += 6)
            {
                if(Bat_Info_Point->BAT_Section[SectionCount].transport_descriptors_length != 0)
                {
                    SectionPosition += Bat_Info_Point->BAT_Section[SectionCount].transport_descriptors_length;
                    ParseTS_Descriptor(Bat_Info_Point->BAT_Section[SectionCount].descriptor);
                }

                printf("------------------------BATSECTION---------------------------\n");
                printf("transport_stream_id = %x\n",Bat_Info_Point->BAT_Section[SectionCount].transport_stream_id);
                printf("original_network_id = %x\n",Bat_Info_Point->BAT_Section[SectionCount].original_network_id);
                printf("reserved_future_use = %x\n",Bat_Info_Point->BAT_Section[SectionCount].reserved_future_use);
                printf("transport_descriptors_length = %x\n",Bat_Info_Point->BAT_Section[SectionCount].transport_descriptors_length);

                SectionCount++;    
            }
        }
        Bat_Info_Point = Bat_Info_Point->next;
    }while (Bat_Info_Point != NULL);
}

void Get_SDT()
{
    TS_SDT *Sdt_Info_Point = TS_PackageSdtPoint->next;

    if(Sdt_Info_Point != NULL)
    do{
        printf("------------------------SDT---------------------------\n");
        printf("talble_id = %x\n",Sdt_Info_Point->table_id);
        printf("section_syntax_indicator = %x\n",Sdt_Info_Point->section_syntax_indicator);
        printf("reserved_future_use_1 = %x\n",Sdt_Info_Point->reserved_future_use_1);
        printf("reserved_1 = %x\n",Sdt_Info_Point->reserved_1);
        printf("section_length = %x\n",Sdt_Info_Point->section_length);
        printf("transport_stream_id = %x\n",Sdt_Info_Point->transport_stream_id);
        printf("reserved_2 = %x\n",Sdt_Info_Point->reserved_2);
        printf("version_number = %x\n",Sdt_Info_Point->version_number);
        printf("current_next_indicator = %x\n",Sdt_Info_Point->current_next_indicator);
        printf("section_number = %x\n",Sdt_Info_Point->section_number);
        printf("last_section_numberr = %x\n",Sdt_Info_Point->last_section_number);
        printf("original_network_id = %x\n",Sdt_Info_Point->original_network_id);
        printf("reserved_future_use_2 = %x\n",Sdt_Info_Point->reserved_future_use_2);
        printf("CRC_32  = %x\n",Sdt_Info_Point->CRC_32);

        int SDT_Length = Sdt_Info_Point->section_length + 3;
        int ServiceCount = 0;
        int ServicePosition = 11;

        for (ServicePosition = 11; ServicePosition < SDT_Length - 4; ServicePosition += 5)
        {
            
            if (Sdt_Info_Point->SDT_Service[ServiceCount].descriptors_loop_length != 0)
            {
                ServicePosition += Sdt_Info_Point->SDT_Service[ServiceCount].descriptors_loop_length; 
                ParseTS_Descriptor(Sdt_Info_Point->SDT_Service[ServiceCount].descriptor);
            }

            printf("-------------------------SDTSECTION--------------------------\n");
            printf("service_id = %x\n",Sdt_Info_Point->SDT_Service[ServiceCount].service_id);
            printf("reserved_future_use = %x\n",Sdt_Info_Point->SDT_Service[ServiceCount].reserved_future_use);
            printf("EIT_schedule_flag = %x\n",Sdt_Info_Point->SDT_Service[ServiceCount].EIT_schedule_flag);
            printf("EIT_present_following_flag = %x\n",Sdt_Info_Point->SDT_Service[ServiceCount].EIT_present_following_flag);
            printf("running_status = %x\n",Sdt_Info_Point->SDT_Service[ServiceCount].running_status);
            printf("free_CA_mode = %x\n",Sdt_Info_Point->SDT_Service[ServiceCount].free_CA_mode);
            printf("descriptors_loop_length = %x\n",Sdt_Info_Point->SDT_Service[ServiceCount].descriptors_loop_length);
        
            ServiceCount++;
        }

        Sdt_Info_Point = Sdt_Info_Point->next;
    }while (Sdt_Info_Point != NULL);
}

void Get_EIT()
{
    TS_EIT *Eit_Info_Point = TS_PackageEitPoint->next;

    if(Eit_Info_Point != NULL)
    do{
        printf("------------------------EIT---------------------------\n");
        printf("talble_id = %x\n",Eit_Info_Point->table_id);
        printf("section_syntax_indicator = %x\n",Eit_Info_Point->section_syntax_indicator);
        printf("reserved_future_use_1 = %x\n",Eit_Info_Point->reserved_future_use);
        printf("reserved_1 = %x\n",Eit_Info_Point->reserved1);
        printf("section_length = %x\n",Eit_Info_Point->section_length);
        printf("service_id = %x\n",Eit_Info_Point->service_id);
        printf("reserved_2 = %x\n",Eit_Info_Point->reserved2);
        printf("version_number = %x\n",Eit_Info_Point->version_number);
        printf("current_next_indicator = %x\n",Eit_Info_Point->current_next_indicator);
        printf("section_number = %x\n",Eit_Info_Point->section_number);
        printf("last_section_numberr = %x\n",Eit_Info_Point->last_section_number);
        printf("transport_stream_id = %x\n",Eit_Info_Point->transport_stream_id);
        printf("original_network_id = %x\n",Eit_Info_Point->original_network_id);
        printf("segment_last_section_number = %x\n",Eit_Info_Point->segment_last_section_number);
        printf("last_table_id= %x\n",Eit_Info_Point->last_table_id);
        printf("CRC_32 = %x\n",Eit_Info_Point->CRC_32);

        int EIT_Length = Eit_Info_Point->section_length + 3;
        int EventPosition = 0;
        int EventCount = 0;
        for (EventPosition = 14; EventPosition < EIT_Length - 4; EventPosition += 12)
        {
            if (Eit_Info_Point->astEIT_Info[EventCount].descriptors_loop_length != 0)
            {
                EventPosition += Eit_Info_Point->astEIT_Info[EventCount].descriptors_loop_length;
                ParseTS_Descriptor(Eit_Info_Point->astEIT_Info[EventCount].descriptor);
            }

            printf("-------------------------EITTSECTION--------------------------\n");
            printf("event_id = %x\n",Eit_Info_Point->astEIT_Info[EventCount].event_id);
            for(int i = 0;i < 5;i++)
            printf("start_time= %x\n",Eit_Info_Point->astEIT_Info[EventCount].start_time[i]);
            printf("duration = %x\n",Eit_Info_Point->astEIT_Info[EventCount].duration);
            printf("running_status = %x\n",Eit_Info_Point->astEIT_Info[EventCount].running_status);
            printf("freed_CA_mode = %x\n",Eit_Info_Point->astEIT_Info[EventCount].freed_CA_mode);
            printf("descriptors_loop_length = %x\n",Eit_Info_Point->astEIT_Info[EventCount].descriptors_loop_length);

            EventCount++;
        }

        Eit_Info_Point = Eit_Info_Point->next;
    }while (Eit_Info_Point != NULL);

}